#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>

const int N = 1005;
int n, m, ans, col[N], dis[N];
int e_cnt, heads[N];
bool vis[N];
std::queue<int> q;

struct Edge {
  int v, nxt;
} e[200005];

inline void add(int u, int v) {
  e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt;
}

inline bool solve(int s) {
  memset(dis, 0x3f, sizeof(dis));
  std::vector<int> vec;
  dis[s] = 0, q.push(s), col[s] = 0, vis[s] = true;
  while (!q.empty()) {
    int u = q.front();
    vec.push_back(u);
    q.pop();
    for (int i = heads[u], v; i; i = e[i].nxt) {
      if (col[v = e[i].v] == col[u]) return false;
      if (col[v] == -1) col[v] = !col[u];
      if (dis[v] > dis[u] + 1) {
        dis[v] = dis[u] + 1;
        if (!vis[v]) q.push(v), vis[v] = true;
      }
    }
  }
  int maxdis = 0;
  for (auto &s : vec) {
    memset(dis, 0x3f, sizeof(dis));
    memset(vis, 0, sizeof(vis));
    dis[s] = 0, q.push(s), vis[s] = true;
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      for (int i = heads[u], v; i; i = e[i].nxt) {
        if (dis[v = e[i].v] > dis[u] + 1) {
          dis[v] = dis[u] + 1;
          if (!vis[v]) q.push(v), vis[v] = true;
        }
      }
    }
    for (auto &i : vec) maxdis = std::max(maxdis, dis[i]);
  }
  ans += maxdis;
  return true;
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("testdata.in", "r", stdin);
  freopen("testdata.out", "w", stdout);
#else
  freopen("merge.in", "r", stdin);
  freopen("merge.out", "w", stdout);
#endif
#endif

  scanf("%d%d", &n, &m);
  for (int i = 1, u, v; i <= m; ++i) scanf("%d%d", &u, &v), add(u, v), add(v, u);
  memset(col, -1, sizeof(col));
  for (int i = 1; i <= n; ++i) {
    if (col[i] == -1)
      if (!solve(i)) return puts("-1"), 0;
  }
  printf("%d", ans);
  return 0;
}